# -*- coding: utf8 -*-
import os
import sqlite3
from datetime import datetime
import time
from functools import wraps
import hashlib

from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash, send_file, Response
from flask.ext.migrate import Migrate, MigrateCommand
from flask.ext.script import Manager
import click

import model
from model.basemodel import db
from model.post import Post
from model.wechat import WeChat
from model.reader import Reader


import qrcode

from setting import *

from wechatlib import WeChatApi
from util import create_signature

# from post.views import posts
# from admin.views import admins

#from api.image import ImageResource
from api.api import api

app = Flask(__name__)
app.config.from_object(__name__)
migrate = Migrate(app, db)

manager = Manager(app)
manager.add_command('db', MigrateCommand)

api.init_app(app)
app.config.from_envvar('FLASK_SETTINGS', silent=True)


def logged_in(f):
    @wraps(f)
    def wrapper(*args, **kwargs):
        if 'logged_in' not in session:
            return redirect(url_for('login', next=request.url))
        return f(*args, **kwargs)
    return wrapper


@app.context_processor
def latest_posts():
    latest = Post.select().order_by(Post.create_time.desc())[0:3]
    return dict(latest=latest)


@app.context_processor
def site_name():
    return dict(site_name=app_name)


@app.context_processor
def wechat():
    '''Add WeChat information'''
    # we = WeChat.get(WeChat.id == 1)
    # timestamp = int(time.time())
    # sign = create_signature(we.get_jsticket(), we.noncestr, timestamp, request.url)
    # return dict(appid=we.appid,timestamp=timestamp,noncestr=we.noncestr,signature = sign, url=request.url)
    return dict()


app.config.update(dict(
    DATABASE=os.path.join(app.root_path, 'babby.db'),
    SECRET_KEY='development key',
    USERNAME='admin',
    PASSWORD='default',
))


@app.template_filter('dateformat')
def datetime_format(value):
    return value.strftime('%Y/%m/%d')


@app.template_filter('clip')
def clip_text(value, count):
    if  isinstance(value, unicode):
        return value[:count]
    else:
        return value


@app.route("/")
def index():
    posts = Post.select().order_by(Post.create_time.desc())
    if len(posts) > 0:
        p = posts[0]
        p.read_count += 1
        p.save()
    else:
        p = None
    return render_template('index.html', post=p)


@app.route("/post")
def post():
    posts = Post.select().order_by(Post.create_time.desc())
    return render_template('posts.html', posts=posts)


@app.route("/about")
def about():
    return render_template('about.html')


@app.route("/qr/", defaults={'pid': 0})
@app.route("/qr/<int:pid>")
def qr(pid):
    if pid == 0:
        url = 'http://%s' % 'www.fangshiyue.com'
    else:
        url = 'http://%s/show/%d' % ('www.fangshiyue.com', pid)

    img = qrcode.make(url)
    buf = StringIO()
    img.save(buf, 'PNG')
    buf.seek(0)
    return send_file(buf, mimetype='image/png', cache_timeout=0)


@app.route('/add', methods=['GET'])
@logged_in
def add():
    return render_template('add.html')


@app.route('/add', methods=['POST'])
@logged_in
def post_add():
    if not session.get('logged_in'):
        abort(401)
    p = Post()
    p.title = request.form['title']
    p.content = request.form['content']
    p.keyword = request.form['keyword']
    p.save()
    return redirect(url_for('post'))


@app.route('/edit/<int:id>', methods=['GET'])
@logged_in
def edit(id):
    if not session.get('logged_in'):
        abort(401)
    p = Post.get(Post.id == id)
    if p is None:
        abort(404)
    return render_template('edit.html', post=p)


@app.route('/edit', methods=['POST'])
@logged_in
def edit_post():
    if not session.get('logged_in'):
        abort(401)
    p = Post.get(Post.id == request.form['id'])
    p.title = request.form['title']
    p.content = request.form['content']
    p.keyword = request.form['keyword']

    p.save()
    return redirect(url_for('post'))


@app.route('/del/<int:id>')
@logged_in
def del_post(id):
    if not session.get('logged_in'):
        abort(401)
    p = Post.delete().where(Post.id == id)
    p.execute()
    flash('The post with id was deleted %d' % id)
    return redirect(url_for('post'))


@app.route('/login', methods=['GET', 'POST'])
def login():
    error = None
    if request.method == 'POST':
        if request.form['username'] != app.config['USERNAME']:
            error = "Invalid user name"
        elif request.form['password'] != app.config['PASSWORD']:
            error = 'Invalid password'
        else:
            session['logged_in'] = True
            next_url = request.form['next']
            if next_url is None or next_url == '':
                logging.debug("logged in")
                return redirect(url_for('post'))
            else:
                return redirect(request.form['next'])
    return render_template('login.html', error=error)


@app.route('/sqlite', methods=['POST'])
@logged_in
def exec_sqlite():
    error = None
    sql = request.form['sql']
    msg = 'Ready'
    if sql is None or len(sql) == 0:
        error = 'SQL cannot be null'
    else:
        try:
            tbl = db.get_tables()
            cur = db.execute_sql(sql)
            res = [x for x in cur.fetchall()]
            cols = [x[0] for x in cur.description]
            msg = msg + 'Affected: %d' % len(res)
        except:
            error = "SQL error"
            res = []

    return render_template('sqlite.html', error=error, sql=sql, msg=msg, cols=cols, res=res)


@app.route('/sqlite', methods=['GET'])
@logged_in
def get_sqlite():
    error =''
    sql = ''
    msg = 'Ready'
    return render_template('sqlite.html', error=error, sql=sql, msg=msg)


@app.route('/logout')
def logout():
    session.pop('logged_in', None)
    return redirect(url_for('index'))


@app.route('/MP_verify_TbWXU0yNL4zhI1Bw.txt')
def weixin_verify():
    return Response('TbWXU0yNL4zhI1Bw', mimetype='text/plain')


# WeChat configuration
@app.route('/wechat/list')
@logged_in
def wechat_view():
    we = WeChat.get(WeChat.id ==1)
    sign = create_signature(we.get_jsticket(), we.noncestr, 13234, request.url)
    return render_template('wechat/list.html', wechat=we, sign = sign)


@app.route('/wechat', methods=['GET',])
@logged_in
def wechat_setting():
    we = WeChat.get(WeChat.id == 1)
    return render_template('wechat/edit.html', wechat=we)


@app.route('/wechat', methods=['POST'])
@logged_in
def wechat_save():
    p = WeChat.get(WeChat.id==1)
    p.appid = request.form['appid']
    p.secret = request.form['secret']
    p.noncestr = request.form['noncestr']
    p.save()
    return redirect(url_for('wechat_view'))


@app.route('/wechat/refresh')
@logged_in
def wechat_refresh():
    we = WeChat.get(WeChat.id==1)
    api = WeChatApi()
    we.token = api.get_token(we.appid, we.secret)
    we.jsticket = api.get_jsticket(we.token)
    we.save()
    return redirect(url_for('wechat_view'))


@app.route('/reader/list')
def reader_list():
    rs = Reader.select().order_by(Reader.create_time.desc())
    return render_template('reader/list.html', readers=rs)


@app.route('/reader/', defaults={'id':-1})
@app.route('/reader/<int:id>')
def reader_show(id):
    readers = Reader.select().order_by(Reader.create_time.desc())
    reader = None
    if id == -1:
        if len(readers)>0:
            reader = readers[0]
    else:
        reader = Reader.get(Reader.id == id)
    return render_template('reader/show.html', reader=reader, readers=readers)


@app.route('/reader/add', methods=['GET',])
@logged_in
def reader_add():
    return render_template('reader/add.html')


@app.route('/reader/add', methods=['POST',])
@logged_in
def reader_add_post():
    if not session.get('logged_in'):
        abort(401)
    p = Reader()
    p.title = request.form['title']
    p.icon_name = request.form['icon_name']
    p.icon_url = request.form['icon_url']
    p.media_type = request.form['media_type']
    p.media_url = request.form['media_url']
    p.description = request.form['description']
    p.create_time = datetime.now()
    p.save()
    return redirect(url_for('reader_list'))


@app.route('/reader/del')
@logged_in
def reader_del():
    return render_template('reader/del.html')


if __name__ == '__main__':
    logging.debug("Started")
    app.run(port=5000, debug=True)
